﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace Deflection
{
    class ParticleSystem
    {
        public Vector2 Position { get; set; }

        public List<Particle> Particles { get; set; }

        public bool Active { get; set; }
        public bool Drawing { get; set; }
        public bool Spawning { get; set; }

        public int SpawnRate { get; set; }
        public int MaximumParticles { get; set; }
        public float minParticleVelocity, maxParticleVelocity;
        public Texture2D Texture { get; set; }
        public Color Color { get; set; }
        public float spriteScale;
        public float fadeRate;
        private int UpdateCounter { get; set; }

        public int MaxLife { get; set; }

        Random rand;
        public ParticleSystem(Vector2 position, Texture2D texture, Color color, float scale)
        {

            Position = position;
            Texture = texture;
            Color = color;
            spriteScale = scale;
            Particles = new List<Particle>();
            minParticleVelocity = 0.0f;
            maxParticleVelocity = 0.0f;
            UpdateCounter = 0;
            rand = new Random((int)this.Position.X * (int)this.Position.Y);
            Active = true;
            Drawing = true;
            Spawning = true;
            fadeRate = 0.9f;
            SpawnRate = 4;
            MaximumParticles = 100;
            MaxLife = 40;
        }
        public ParticleSystem(Vector2 position, Texture2D texture, Color color, float scale, float FadeRate)
        {
            
            Position = position;
            Texture = texture;
            Color = color;
            spriteScale = scale;
            Particles = new List<Particle>();
            minParticleVelocity = 0.0f;
            maxParticleVelocity = 0.0f;
            UpdateCounter = 0;
            rand = new Random((int)this.Position.X * (int)this.Position.Y);
            Active = true;
            Drawing = true;
            Spawning = true;
            fadeRate = FadeRate;
            SpawnRate = 4;
            MaximumParticles = 100;
            MaxLife = 40;
        }

        public virtual  void Update(GameTime gameTime)
        {
            #region Update particles
 
            for (int i = 0; i < Particles.Count; i++)
            {
                // Remove old particles
                if (Particles[i].Life > Particles[i].MaxLife)
                {
                    Particles.RemoveAt(i);
                }
                else
                {
                    Particles[i].Update(gameTime);
                }
            }

            #endregion Update particles

            #region Spawn particles

            // Check if we are spawning particles
            if (Spawning)
            {
                SpawnParticles(gameTime);
            }

            #endregion Spawn partciles

        }

        public virtual void Draw(GameTime gameTime, SpriteBatch spriteBatch)
        {
            if (Drawing)
            {
                for (int i = 0; i < Particles.Count; i++)
                {
                    Particles[i].Draw(gameTime, spriteBatch);
                }
            }
        }

        public bool HasFreeParticles()
        {
            if (Particles.Count >= MaximumParticles)
            {
                return false;
            }
            return true;
        }

        public Particle SpawnParticle(Vector2 position, Color color, float scale)
        {
            float xVel = rand.Next((int)minParticleVelocity, (int)maxParticleVelocity+1);
            float yVel = rand.Next((int)minParticleVelocity, (int)maxParticleVelocity+1);
            return new Particle(position, color, new Vector2(xVel, yVel), Texture, scale, MaxLife, fadeRate);
        }

        public virtual void SpawnParticles(GameTime gameTime)
        {
            // Check if we are able to spawn particles
            if (HasFreeParticles())
            {
                UpdateCounter++;
                if (UpdateCounter >= SpawnRate)
                {
                    rand = new Random(gameTime.TotalGameTime.Milliseconds * (int)this.Position.X * (int)this.Position.Y);
                    Particles.Add(SpawnParticle(Position + new Vector2(rand.Next(-10, 10), rand.Next(-10, 10)), Color, spriteScale));
                    UpdateCounter = 0;
                }
            }
        }

    }
}
